package ducct.footprint.location;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

import com.google.android.maps.GeoPoint;

import ducct.footprint.ui.MyFootprintListActivity;

public class MyLocationListener implements LocationListener {
	public final String TAG = getClass().getSimpleName();
	
	private static final int TIME_TO_ACCEPT_LAST_LOCATION = 1000 * 60 * 10;	// 10 minutes
	private static final int NUM_WAIT_TO_GET_LOCATION = 30;	// wait 30 seconds to get location
	
	private LocationManager locationManager;
	private Location lastLocation;
	
	private static MyLocationListener instance = null;
	
	public static MyLocationListener getInstance() {
		if (instance == null) {
			instance = new MyLocationListener(MyFootprintListActivity.getInstance());
		}
		
		return instance;
	}
	
	public static MyLocationListener getInstance(Context context) {
		if (instance == null) {
			instance = new MyLocationListener(context);
		}
		
		return instance;
	}

	private MyLocationListener(Context context) {
		locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
	}
	
	private long lastTime = 0L;
	public void onLocationChanged(Location loc) {
		Log.d(TAG, "onLocationChanged");
		lastTime = System.currentTimeMillis();
		
		lastLocation = loc;
	}
	
	public Location getCurrentLocation() {
		long currentMiliseconds = System.currentTimeMillis();
		
		if (lastLocation != null) {
			if ( (currentMiliseconds - lastTime) < TIME_TO_ACCEPT_LAST_LOCATION ) {
				return lastLocation;
			}
		} 
		
		Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		if (location == null) {
			location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		}
		if (location != null) {
			if (currentMiliseconds - lastTime < TIME_TO_ACCEPT_LAST_LOCATION) {
				return location;
			}
		}
		
		return null;
	}
	
	public void waitForLocation(final MyLocationCallback callback) {
		new Thread() {
			@Override
			public void run() {
				for (int i = 0; i < NUM_WAIT_TO_GET_LOCATION; ++i) {
					Log.d(TAG, "Try to get location number " + i);
					if (lastLocation != null) {
						callback.onGotCurrentLocation(lastLocation);
						break;
					}
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						callback.onCannotGetLocation();
						e.printStackTrace();
					}
				}
				
				if (lastLocation == null) {
					callback.onCannotGetLocation();
				}
			}
		}.start();
	}

	public void onProviderDisabled(String provider) {
		Log.d(TAG, "Location provider disabled");
	}

	public void onProviderEnabled(String provider) {
		Log.d(TAG, "Location provider enabled");
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
	}
	
	public void removeUpdates() {
		Log.d(TAG, "Remove location update requests");
		locationManager.removeUpdates(this);
	}
}